
/*
 * FaceCat图形通讯框架
 * 著作权编号:2015SR229355+2020SR0266727
 * 上海卷卷猫信息技术有限公司
 */

#include "../../stdafx.h"
#include "../../include/div/FCSplitLayoutDiv.h"

namespace FaceCat{
	FCSplitLayoutDiv::FCSplitLayoutDiv(){
		m_datumSize.cx = 0;
		m_datumSize.cy = 0;
		m_firstView = 0;
		m_oldSize.cx = 0;
		m_oldSize.cy = 0;
		m_secondView = 0;
		m_splitMode = FCSizeType_AbsoluteSize;
		m_splitPercent = -1;
		m_splitter = 0;
	}

	FCSplitLayoutDiv::~FCSplitLayoutDiv(){
		m_firstView = 0;
		m_secondView = 0;
		if(m_splitter){
			m_splitter->removeEvent((FCEventCallBack*)this, L"ondragging");
		}
		m_splitter = 0;
	}

	FCSize FCSplitLayoutDiv::getDatumSize(){
		return m_datumSize;
	}

	void FCSplitLayoutDiv::setDatumSize(FCSize value){
		m_datumSize = value;
	}

	FCView* FCSplitLayoutDiv::getFirstView(){
		return m_firstView;
	}

	void FCSplitLayoutDiv::setFirstView(FCView *value){
		m_firstView = value;
	}

	FCView* FCSplitLayoutDiv::getSecondView(){
		return m_secondView;
	}

	void FCSplitLayoutDiv::setSecondView(FCView *value){
		m_secondView = value;
	}

	FCSizeType FCSplitLayoutDiv::getSplitMode(){
		return m_splitMode;
	}

	void FCSplitLayoutDiv::setSplitMode(FCSizeType value){
		m_splitMode = value;
	}

	FCButton* FCSplitLayoutDiv::getSplitter(){
		return m_splitter;
	}

	///////////////////////////////////////////////////////////////////////////////////////////////////////

	void FCSplitLayoutDiv::callEvent(String eventName, Object sender, Object invoke){
		FCLayoutDiv::callEvent(eventName, sender, invoke);
		if (eventName == L"ondragging" && sender == m_splitter) {
            m_splitPercent = -1;
            update();
            invalidate();
        }
	}
	
	String FCSplitLayoutDiv::getViewType(){
		return L"SplitLayoutDiv";
	}

	void FCSplitLayoutDiv::getAttribute(const String& name, String *value, String *type){
		if(name == L"candragsplitter"){
			*type = L"bool";
			if (m_splitter){
				*value = FCTran::boolToStr(m_splitter->allowDrag());
            }
			else{
				*value = L"False";
			}
		}else if(name == L"datumsize"){
			*type = L"size";
			*value = FCTran::sizeToStr(getDatumSize());
		}
        else if (name == L"splitmode"){
			*type = L"enum:FCSizeType";
            if (getSplitMode() == FCSizeType_AbsoluteSize){
                *value = L"AbsoluteSize";
            }
            else{
                *value = L"PercentSize";
            }
        }
		else if ((int)name.find(L"splitter-") != -1){
            if (m_splitter){
                m_splitter->getAttribute(name.substr(9), value, type);
            }
        }
		else if (name == L"splitterposition"){
            *type = L"str";
            if (m_splitter) {
                if (m_layoutStyle == FCLayoutStyle_TopToBottom || m_layoutStyle == FCLayoutStyle_BottomToTop) {
					*value = FCTran::intToStr(m_splitter->getTop());
                    if (m_splitter->getHeight() > 0) {
						*value = *value + String(L",") + FCTran::intToStr(m_splitter->getHeight());
                    }
                } else {
					*value = FCTran::intToStr(m_splitter->getLeft());
                    if (m_splitter->getWidth() > 0) {
						*value = *value + String(L",") + FCTran::intToStr(m_splitter->getWidth());
                    }
                }
            }
        }
        else if (name == L"splittervisible"){
			*type = L"bool";
            if (m_splitter){
				*value = FCTran::boolToStr(m_splitter->isVisible());
            }
			else{
				*value = L"False";
			}
        }
		else{
			FCLayoutDiv::getAttribute(name, value, type);
		}
	}

	ArrayList<String> FCSplitLayoutDiv::getAttributeNames(){
		ArrayList<String> attributeNames = FCDiv::getAttributeNames();
		attributeNames.add(L"CanDragSplitter");
		attributeNames.add(L"DatumSize");
		attributeNames.add(L"SplitMode");
		attributeNames.add(L"SplitterPosition");
		attributeNames.add(L"SplitterVisible");
		return attributeNames;
	}

	void FCSplitLayoutDiv::onLoad(){
		FCLayoutDiv::onLoad();
		if (!m_splitter){
			FCHost *host = getNative()->getHost();
			m_splitter = dynamic_cast<FCButton*>(host->createInternalView(this, L"splitter"));
			m_splitter->addEvent((FCEventCallBack*)this, L"ondragging", this);
			addView(m_splitter);
		}
	}

	bool FCSplitLayoutDiv::onResetLayout(){
		bool reset = false;
		if(getNative() && m_splitter && m_firstView && m_secondView){
			FCRect splitRect = {0};
			int width = getWidth(), height = getHeight();
			FCRect fRect = {0};
			FCRect sRect = {0};
			FCSize splitterSize = {0};
			if(m_splitter->isVisible()){
				splitterSize.cx = m_splitter->getWidth();
				splitterSize.cy = m_splitter->getHeight();
			}
			FCLayoutStyle layoutStyle = getLayoutStyle();
			switch (layoutStyle){
				case FCLayoutStyle_BottomToTop:
					if (m_splitMode == FCSizeType_AbsoluteSize || m_oldSize.cy == 0){
						splitRect.left = 0;
						splitRect.top = height - (m_oldSize.cy - m_splitter->getTop());
						splitRect.right = width;
						splitRect.bottom = splitRect.top + splitterSize.cy;
					}
					else if (m_splitMode == FCSizeType_PercentSize){
						splitRect.left = 0;
						if(m_splitPercent == -1){
							m_splitPercent = (float)m_splitter->getTop() / m_oldSize.cy;
						}
						splitRect.top = (int)(height * m_splitPercent);
						splitRect.right = width;
						splitRect.bottom = splitRect.top + splitterSize.cy;
					}
					fRect.left = 0;
					fRect.top = splitRect.bottom;
					fRect.right = width;
					fRect.bottom = height;
					sRect.left = 0;
					sRect.top = 0;
					sRect.right = width;
					sRect.bottom = splitRect.top;
					break;
				case FCLayoutStyle_LeftToRight:
					if (m_splitMode == FCSizeType_AbsoluteSize || m_oldSize.cx == 0){
						splitRect.left = m_splitter->getLeft();
						splitRect.top = 0;
						splitRect.right = splitRect.left + splitterSize.cx;
						splitRect.bottom = height;
					}
					else if (m_splitMode == FCSizeType_PercentSize){
						if(m_splitPercent == -1){
							m_splitPercent = (float)m_splitter->getLeft() / m_oldSize.cx;
						}
						splitRect.left = (int)(width * m_splitPercent);
						splitRect.top = 0;
						splitRect.right = splitRect.left + splitterSize.cx;
						splitRect.bottom = height;
					}
					fRect.left = 0;
					fRect.top = 0;
					fRect.right = splitRect.left;
					fRect.bottom = height;
					sRect.left = splitRect.right;
					sRect.top = 0;
					sRect.right = width;
					sRect.bottom = height;
					break;
				case FCLayoutStyle_RightToLeft:
					if (m_splitMode == FCSizeType_AbsoluteSize || m_oldSize.cx == 0){
						splitRect.left = width - (m_oldSize.cx - m_splitter->getLeft());
						splitRect.top = 0;
						splitRect.right = splitRect.left + splitterSize.cx;
						splitRect.bottom = height;
					}
					else if (m_splitMode == FCSizeType_PercentSize){
						if(m_splitPercent == -1){
							m_splitPercent = (float)m_splitter->getLeft() / m_oldSize.cx;
						}
						splitRect.left = (int)(width * m_splitPercent);
						splitRect.top = 0;
						splitRect.right = splitRect.left + splitterSize.cx;
						splitRect.bottom = height;
					}
					fRect.left = splitRect.right;
					fRect.top = 0;
					fRect.right = width;
					fRect.bottom = height;
					sRect.left = 0;
					sRect.top = 0;
					sRect.right = splitRect.left;
					sRect.bottom = height;
					break;
				case FCLayoutStyle_TopToBottom:
					if (m_splitMode == FCSizeType_AbsoluteSize || m_oldSize.cy == 0){
						splitRect.left = 0;
						splitRect.top = m_splitter->getTop();
						splitRect.right = width;
						splitRect.bottom = splitRect.top + splitterSize.cy;
					}
					else if (m_splitMode == FCSizeType_PercentSize){
						splitRect.left = 0;
						if(m_splitPercent == -1){
							m_splitPercent = (float)m_splitter->getTop() / m_oldSize.cy;
						}
						splitRect.top = (int)(height * m_splitPercent);
						splitRect.right = width;
						splitRect.bottom = splitRect.top + splitterSize.cy;
					}
					fRect.left = 0;
					fRect.top = 0;
					fRect.right = width;
					fRect.bottom = splitRect.top;
					sRect.left = 0;
					sRect.top = splitRect.bottom;
					sRect.right = width;
					sRect.bottom = height;
					break;
			}
			if(m_splitter->isVisible()){
				FCRect spRect = m_splitter->getBounds();
                if (spRect.left != splitRect.left || spRect.top != splitRect.top || spRect.right != splitRect.right || spRect.bottom != splitRect.bottom){
                    m_splitter->setBounds(splitRect);
                    reset = true;
                }
				if(m_splitter->allowDrag()){
					if(layoutStyle == FCLayoutStyle_LeftToRight || layoutStyle == FCLayoutStyle_RightToLeft){
						m_splitter->setCursor(FCCursors_SizeWE);
					}
					else{
						m_splitter->setCursor(FCCursors_SizeNS);
					}
					m_splitter->bringToFront();
				}
			}
			FCRect fcRect = m_firstView->getBounds();
            if (fcRect.left != fRect.left || fcRect.top != fRect.top || fcRect.right != fRect.right || fcRect.bottom != fRect.bottom){
                reset = true;
                m_firstView->setBounds(fRect);
                m_firstView->update();
            }
			FCRect scRect = m_secondView->getBounds();
            if (scRect.left != sRect.left || scRect.top != sRect.top || scRect.right != sRect.right || scRect.bottom != sRect.bottom){
                reset = true;
                m_secondView->setBounds(sRect);
                m_secondView->update();
            }
		}
		m_oldSize = getSize();
		return reset;
	}

	void FCSplitLayoutDiv::setAttribute(const String& name, const String& value){
		if(name == L"candragsplitter"){
			if (m_splitter){
				m_splitter->setAllowDrag(FCTran::strToBool(value));
			}
		}else if(name == L"datumsize"){
			setDatumSize(FCTran::strToSize(value));
		}
        else if (name == L"splitmode"){
			String lowerStr = FCTran::toLower(value);
            if (lowerStr == L"absolutesize"){
                setSplitMode(FCSizeType_AbsoluteSize);
            }
            else{
				setSplitMode(FCSizeType_PercentSize);
            }
        }
		else if ((int)name.find(L"splitter-") != -1){
            if (m_splitter){
                m_splitter->setAttribute(name.substr(9), value);
            }
        }
		else if (name == L"splitterposition"){
            if (m_splitter){
				ArrayList<String> strs = FCTran::split(value, L",");
				if (strs.size() == 4) {
					m_splitter->setBounds(FCTran::strToRect(value));
				} else if (strs.size() <= 2) {
					int pos = FCTran::strToInt(strs.get(0));
					int lWidth = 0;
					if (strs.size() == 2) {
						lWidth = FCTran::strToInt(strs.get(1));
					}
					int width = getWidth(), height = getHeight();
					if(m_datumSize.cx > 0 && m_datumSize.cy > 0){
						m_oldSize = m_datumSize;
					}
					m_splitPercent = -1;
					if (m_layoutStyle == FCLayoutStyle_TopToBottom || m_layoutStyle == FCLayoutStyle_BottomToTop) {
						FCRect bounds = {0, pos, width, pos + lWidth};
						m_splitter->setBounds(bounds);
					} else {
						FCRect bounds = {pos, 0, pos + lWidth, height};
						m_splitter->setBounds(bounds);
					}
				}
            }
        }
        else if (name == L"splittervisible"){
            if (m_splitter){
				m_splitter->setVisible(FCTran::strToBool(value));
            }
        }
        else{
			FCLayoutDiv::setAttribute(name, value);
        }
	}

	void FCSplitLayoutDiv::update(){
		if(m_native && !m_native->m_lockUpdate){
			onResetLayout();
			int viewsSize = (int)m_views.size();
			for (int i = 0; i < viewsSize; i++){
				m_views.get(i)->update();
			}
		}
	}
}